home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 3
/
Cream of the Crop 3.iso
/
comm
/
wnos5src.zip
/
SESSION.C
< prev
next >
Wrap
Text File
|
1993-08-09
|
9KB
|
451 lines
/* Session control */
#include <stdio.h>
#include "global.h"
#include "config.h"
#include "mbuf.h"
#include "proc.h"
#include "ftp.h"
#include "icmp.h"
#include "telnet.h"
#include "tty.h"
#include "session.h"
#include "hardware.h"
#include "socket.h"
#include "cmdparse.h"
#include "commands.h"
#include "files.h"
#include "usock.h"
struct session *Sessions, *Current, *Lastcurr;
extern struct proc *Display;
#define LWRAP 63
char Notval[] = "Not a valid control block\n";
char Nosess[] = "Too many sessions\n";
char *Sestypes[] = {
"",
"Telnet",
"FTP",
"AX25",
"Finger",
"Ping",
"NET/ROM",
"Command",
"More",
"Hopcheck",
"Tip",
"PPP PAP",
"Trace",
"RawIF"
};
/* Convert a character string containing a decimal session index number
* into a pointer. If the arg is NULLCHAR, use the current default session.
* If the index is out of range or unused, return NULLSESSION.
*/
struct session *
sessptr(char *cp)
{
unsigned int i;
struct session *sp;
if(cp == NULLCHAR) {
sp = Lastcurr;
} else if((i = atoi(cp)) >= Nsessions) {
sp = NULLSESSION;
} else {
sp = &Sessions[i + 1];
}
if(sp == NULLSESSION || sp->type == FREE) {
tputs("Invalid or inactive session\n");
return NULLSESSION;
}
return sp;
}
/* Select and display sessions */
int
dosession(int argc,char **argv,void *p)
{
struct sockaddr fsocket;
int i = SOCKSIZE, k, s, r, t;
char *cp, limbo[] = "Limbo!";
struct session *sp = (struct session *)p;
if(argc > 1) {
if((sp = sessptr(argv[1])) != NULLSESSION) {
go(0,0,sp);
}
return 0;
}
tputs(" # S# Type Rcv-Q Snd-Q State Remote socket\n");
for(sp = Sessions; sp < &Sessions[Nsessions]; sp++) {
if(sp->type == FREE || sp->type == COMMAND || sp->type == TRACESESSION) {
continue;
}
/* Rcv-Q includes output pending at the screen driver */
r = socklen(sp->output,1);
t = 0;
cp = NULLCHAR;
if((s = sp->s) != -1){
k = getpeername(s,(char *)&fsocket,&i);
r += socklen(s,0);
t += socklen(s,1);
cp = sockstate(s);
}
tprintf("%c%-3u%-4d",
(Lastcurr == sp) ? '*' : ' ',
(unsigned)(sp - Sessions) - 1,
s);
tprintf("%-8s%6d%6d %-13s%s",
Sestypes[sp->type],
r,
t,
(cp != NULLCHAR) ? cp : limbo,
(sp->name != NULLCHAR) ? sp->name : "");
if(sp->s != -1 && k == 0) {
tprintf(" (%s)",psocket(&fsocket));
}
tputs("\n");
if(sp->type == FTP && (s = sp->cb.ftp->data) != -1){
/* Display data channel, if any */
k = getpeername(s,(char *)&fsocket,&i);
r = socklen(s,0);
t = socklen(s,1);
cp = sockstate(s);
tprintf(" %-4d%-8s%6d%6d %-13s%s",
s,
Sestypes[sp->type],
r,
t,
(cp != NULLCHAR) ? cp : limbo,
(sp->name != NULLCHAR) ? sp->name : "");
if(k == 0) {
tprintf(" (%s)",psocket(&fsocket));
}
tputs("\n");
}
if(sp->rfile != NULLCHAR) {
tprintf(" Record: %s\n",sp->rfile);
}
if(sp->ufile != NULLCHAR) {
tprintf(" Upload: %s\n",sp->ufile);
}
}
return 0;
}
/* Resume current session, and wait for it */
int
go(int argc,char **argv,void *p)
{
struct session *sp = (struct session *)p, *sptmp = Current;
if(sp == NULLSESSION
|| sp->type == FREE
|| (sptmp == Trace && sp->type == TRACESESSION)
|| (sptmp == Command && sp->type == COMMAND)) {
return 0;
}
swapscreen(sptmp,sp);
psignal(sp,0);
Current = sp;
return 0;
}
int
doclose(int argc,char **argv,void *p)
{
struct session *sp = (struct session *)p;
if(argc > 1) {
sp = sessptr(argv[1]);
}
if(sp == NULLSESSION) {
return -1;
}
if(sp->type == FTP || sp->type == MORE) {
/* Unwedge anyone waiting for a domain resolution, etc */
alert(sp->proc,(void *)EABORT);
}
shutdown(sp->s,1);
return 0;
}
int
doreset(int argc,char **argv,void *p)
{
struct session *sp = (struct session *)p;
if(argc > 1) {
sp = sessptr(argv[1]);
}
if(sp == NULLSESSION) {
return -1;
}
/* Unwedge anyone waiting for a domain resolution, etc */
alert(sp->proc,(void *)EABORT);
if(sp->type == FTP) {
shutdown(sp->cb.ftp->data,2);
}
shutdown(sp->s,2);
return 0;
}
int
dokick(int argc,char **argv,void *p)
{
struct session *sp = (struct session *)p;
if(argc > 1) {
sp = sessptr(argv[1]);
}
if(sp == NULLSESSION){
return -1;
}
if(sp->type == FTP) {
sockkick(sp->cb.ftp->data);
}
sockkick(sp->s);
return 0;
}
struct session *
newsession(char *name,int type,int Flag)
{
int i;
struct session *sp;
for(i = 0, sp = Sessions; i < Nsessions; sp++, i++) {
if(sp->type == FREE) {
break;
}
}
if(i == Nsessions) {
return NULLSESSION;
}
sp->proc = Curproc;
sp->type = type;
sp->s = -1;
if(name != NULLCHAR) {
sp->name = strxdup(name);
}
/* Create standard input and output sockets. Output is
* translated to local end-of-line by default
*/
Curproc->input = sp->input = socket(AF_LOCAL,SOCK_STREAM,0);
seteol(Curproc->input,Eol);
sockmode(Curproc->input,SOCK_BINARY);
Curproc->output = sp->output = socket(AF_LOCAL,SOCK_STREAM,0);
seteol(Curproc->output,Eol);
sockmode(Curproc->output,SOCK_ASCII);
/* on by default */
sp->ttystate.crnl = sp->ttystate.edit = sp->ttystate.echo = 1;
/* off by default */
sp->flowmode = sp->morewait = sp->cont = 0;
sp->split = Flag & SPLIT;
sp->swap = Flag & SWAP;
sp->lwrap = LWRAP;
sp->row = (sp->split) ? Nrows - 5 : Nrows - 3;
newscreen(sp);
if(sp->swap) {
swapscreen(Current,sp);
Current = sp;
}
return sp;
}
void
freesession(struct session *sp)
{
if(sp == NULLSESSION)
return;
usflush(sp->output);
pwait(NULL);
if(sp->proc1 != NULLPROC) {
killproc(sp->proc1);
sp->proc1 = NULLPROC;
}
if(sp->proc2 != NULLPROC) {
killproc(sp->proc2);
sp->proc2 = NULLPROC;
}
free_p(sp->ttystate.line);
sp->ttystate.line = NULLBUF;
if(sp->s != -1) {
close_s(sp->s);
}
if(sp->record != NULLFILE) {
Fclose(sp->record);
xfree(sp->rfile);
}
if(sp->upload != NULLFILE) {
Fclose(sp->upload);
xfree(sp->ufile);
}
if(sp->name != NULLCHAR)
xfree(sp->name);
sp->name = NULLCHAR;
sp->rfile = NULLCHAR;
sp->record = NULLFILE;
sp->ufile = NULLCHAR;
sp->upload = NULLFILE;
close_s(sp->input);
close_s(sp->output);
freescreen(sp);
sp->type = FREE;
if(Current == sp){
Current = (Lastcurr == Trace) ? Trace : Command;
swapscreen(NULLSESSION,Current);
alert(Display,(void *)1);
}
if(Lastcurr == sp)
Lastcurr = NULLSESSION;
}
/* Control session recording */
int
dorecord(int argc,char **argv,void *p)
{
struct session *sp = (struct session *)p;
if(argc > 2) {
sp = sessptr(argv[1]);
argc--;
argv++;
}
if(sp == NULLSESSION) {
return -1;
}
if(argc > 1){
if(sp->rfile != NULLCHAR){
Fclose(sp->record);
sp->record = NULLFILE;
xfree(sp->rfile);
sp->rfile = NULLCHAR;
}
/* Open new record file, unless file name is "off", which means
* disable recording
*/
if(strcmp(argv[1],"off") != 0){
if((sp->record = Fopen(argv[1],
(sockmode(sp->output,-1) == SOCK_ASCII) ? APPEND_TEXT : APPEND_BINARY,
0,1)) == NULLFILE) {
return -1;
} else {
sp->rfile = strxdup(argv[1]);
}
}
}
if(sp->rfile != NULLCHAR) {
tprintf("Recording into %s\n",sp->rfile);
} else {
tputs("Recording off\n");
}
return 0;
}
int
dowrap(int argc,char **argv,void *p)
{
struct session *sp = (struct session *)p;
int16 i;
if(argc > 1 && atoi(argv[1]) < 30) {
sp = sessptr(argv[1]);
argc--;
argv++;
}
if(sp == NULLSESSION) {
return -1;
}
i = sp->lwrap;
setintrc(&i,"Wrap",argc,argv,30,132);
sp->lwrap = i;
return 0;
}
/* Control file transmission */
int
doupload(int argc,char **argv,void *p)
{
struct session *sp = (struct session *)p;
if(argc > 2) {
sp = sessptr(argv[1]);
argc--;
argv++;
}
if(sp == NULLSESSION) {
return -1;
}
if(argc < 2) {
tprintf("Uploading %s\n",(sp->ufile != NULLCHAR) ? sp->ufile : "off");
return 0;
}
if(strcmp(argv[1],"off") == 0 && sp->upload != NULLFILE) {
/* Abort upload */
Fclose(sp->upload);
sp->upload = NULLFILE;
xfree(sp->ufile);
sp->ufile = NULLCHAR;
return 0;
}
/* Open upload file */
if((sp->upload = Fopen(argv[1],READ_TEXT,0,1)) == NULLFILE) {
return -1;
}
sp->ufile = strxdup(argv[1]);
/* All set, invoke the upload process */
sp->proc2 = newproc("upload",1024,upload,0,sp,NULL,0);
return 0;
}
/* File uploading task */
static void
upload(int unused,void *sp1,void *p)
{
char line[LINELEN];
struct session *sp = (struct session *)sp1;
/* Disable newline buffering for the duration */
int oldf = setflush(sp->s,-1);
while(sp->ufile != NULLCHAR && fgets(line,LINELEN,sp->upload) != NULL) {
usputs(sp->s,line);
}
usflush(sp->s);
setflush(sp->s,oldf);
Fclose(sp->upload);
sp->upload = NULLFILE;
xfree(sp->ufile);
sp->ufile = NULLCHAR;
sp->proc2 = NULLPROC;
}